﻿using Microsoft.EntityFrameworkCore;
using Polaris.Common;
using Polaris.Domain.Interfaces.Admin;
using Polaris.Domain.Model.DbEntity;
using Polaris.Domain.Model.Dto.Sys_Dictionary.Response;
using Polaris.Domain.Model.Dto.Sys_Dictionary_Item.Request;
using Polaris.Domain.Model.Dto.Sys_Dictionary_Item.Response;
using Polaris.Domain.Model.Dto.Tag.Response;
using Polaris.Domain.Model.Entity.Base;
using Polaris.Domain.Model.Entity.Exception;
using Polaris.Domain.Model.Enum;
using Polaris.Domain.Repository.Interfaces;
using Polaris.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Polaris.Infrastructure.DomainService.Admin
{
    public class Sys_Dictionary_ItemService : ISys_Dictionary_Item
    {
        private readonly IBaseRepository<Sys_Dictionary_Item> _dictionaryItemRepository;
        private readonly PolarisDbContext _dbContext;

        public Sys_Dictionary_ItemService(IBaseRepository<Sys_Dictionary_Item> dictionaryItemRepository, PolarisDbContext dbContext)
        {
            _dictionaryItemRepository = dictionaryItemRepository;
            _dbContext = dbContext;
        }

        /// <summary>
        /// 创建字典项
        /// </summary>
        /// <param name="create"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task CreateDictionaryItem(CreateDictionaryItemRequest create, Guid? userId)
        {
            try
            {
                var dictItem = new Sys_Dictionary_Item()
                {
                    Id = Guid.NewGuid(),
                    DictionaryId = create.DictionaryId,
                    Name = create.Name,
                    Sort = create.Sort,
                    Value = create.Value,
                    CreateBy = userId,
                    CreatedTime = DateTime.Now,
                    Description = create.Description,
                    Enable = create.Enable,
                    IsDelete = false,
                    ParentId = create.ParentId,
                    UpdatedBy = null,
                    UpdatedTime = null
                };
                await _dictionaryItemRepository.AddEntityAsync(dictItem);
                await _dictionaryItemRepository.CommitAsync();
            }
            catch (Exception ex)
            {
                throw new CustomException(ResultCode.FAIL, ex.Message);
            }
        }

        /// <summary>
        /// 删除字典项
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task DeleteDictionaryItem(string id, Guid? userId)
        {
            var dict = await _dictionaryItemRepository.WhereLoadEntityAsNoTrackingAsync(d => d.Id.ToString() == id) ??
                        throw new CustomException(ResultCode.NO_DATA, $"字典项中找不到Id是 {id} 的数据");

            dict.IsDelete = true;
            dict.UpdatedBy = userId;
            dict.UpdatedTime = DateTime.Now;

            _dictionaryItemRepository.UpdateEntity(dict);
            await _dictionaryItemRepository.CommitAsync();
        }

        /// <summary>
        /// 根据字典id获取字典项列表
        /// </summary>
        /// <param name="search"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<PaginationInfo<DictionaryItemInfoResponse>> GetDictionaryItemListByDid(SearchDictionaryItemRequest search)
        {
            try
            {
                Expression<Func<Sys_Dictionary_Item, bool>> where = e => e.IsDelete == false;
                where = where.And(e => e.DictionaryId.ToString() == search.DictionaryId);
                where = where.AndIF(search.Name != null, e => e.Name.Contains(search.Name));
                where = where.AndIF(search.Value != null, e => e.Value.Contains(search.Value));
                var dictItemList = (await _dictionaryItemRepository.LoadEntityListAsync(where, e => e.Sort, "desc", search.PageIndex, search.PageSize))
                    .Select(d => new DictionaryItemInfoResponse
                    {
                        CreateBy = d.CreateBy.ToString(),
                        CreatedTime = d.CreatedTime,
                        Description = d.Description,
                        DictionaryId = d.DictionaryId,
                        Enable = d.Enable,
                        Id = d.Id,
                        Name = d.Name,
                        ParentId = d.ParentId == null ? null : d.ParentId.ToString(),
                        Sort = d.Sort,
                        UpdatedBy = d.UpdatedBy.ToString(),
                        UpdatedTime = d.UpdatedTime,
                        Value = d.Value,
                    }).ToList();
                var total = await _dictionaryItemRepository.GetEntitiesCountAsync(where);

                return ApiResult.CreatePaginationInfo<DictionaryItemInfoResponse>(
                                                                               PageIndex: search.PageIndex,
                                                                               PageSize: search.PageSize,
                                                                               Total: total,
                                                                               Result: dictItemList
                                                                              );
            }
            catch (Exception ex)
            {
                throw new CustomException(ResultCode.FAIL, ex.Message);
            }
        }

        /// <summary>
        /// 根据id获取字典项信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<DictionaryItemInfoResponse> GetDictionaryItemById(string id)
        {
            Expression<Func<Sys_Dictionary_Item, bool>> where = e => e.IsDelete == false;
            where = where.And(e => e.Id.ToString() == id);

            var dictItem = await _dictionaryItemRepository.WhereLoadEntityAsync(where);
            var result =
                 new DictionaryItemInfoResponse
                 {
                     CreateBy = dictItem.CreateBy.ToString(),
                     CreatedTime = dictItem.CreatedTime,
                     Description = dictItem.Description,
                     DictionaryId = dictItem.DictionaryId,
                     Enable = dictItem.Enable,
                     Id = dictItem.Id,
                     Name = dictItem.Name,
                     ParentId = dictItem.ParentId == null ? null : dictItem.ParentId.ToString(),
                     Sort = dictItem.Sort,
                     UpdatedBy = dictItem.UpdatedBy.ToString(),
                     UpdatedTime = dictItem.UpdatedTime,
                     Value = dictItem.Value,
                 };


            return result;
        }

        /// <summary>
        /// 根据字典值获取字典项
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public async Task<List<D_ItemOptionResponse>> GetDictionaryItemByCode(string code)
        {
            var linqStr = from dItem in _dbContext.Sys_Dictionary_Item
                          join d in _dbContext.Sys_Dictionary
                          on dItem.DictionaryId equals d.Id
                          where d.Code == code && !d.IsDelete && !dItem.IsDelete
                          select new
                          {
                              dItem.Id,
                              dItem.Name
                          };

            var result = new List<D_ItemOptionResponse>();
            var list = await linqStr.ToListAsync();
            list.ForEach(data =>
            {
                result.Add(new D_ItemOptionResponse()
                {
                    Id = data.Id.ToString(),
                    Value = data.Name
                });
            });
            return result;
        }

        /// <summary>
        /// 修改字典项
        /// </summary>
        /// <param name="update"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task UpdateDictionaryItem(UpdateDictionaryItemRequest update, Guid? userId)
        {
            try
            {
                var dictItem = await _dictionaryItemRepository.WhereLoadEntityAsNoTrackingAsync(d => d.Id.ToString() == update.Id) ??
                           throw new CustomException(ResultCode.NO_DATA, $"字典项中找不到Id是 {update.Id} 的数据");

                dictItem.DictionaryId = update.DictionaryId;
                dictItem.Sort = update.Sort;
                dictItem.ParentId = update.ParentId;
                dictItem.Description = update.Description;
                dictItem.Value = update.Value;
                dictItem.Name = update.Name;
                dictItem.Enable = update.Enable;
                dictItem.UpdatedBy = userId;
                dictItem.UpdatedTime = DateTime.Now;
                _dictionaryItemRepository.UpdateEntity(dictItem);
                await _dictionaryItemRepository.CommitAsync();
            }
            catch (Exception ex)
            {
                throw new CustomException(ResultCode.FAIL, ex.Message);
            }
        }
    }
}
